pub mod server;

use serde::{Deserialize, Serialize};
pub use server::Serve;

use crate::{sql::{Table, Value}, storage::Entry};

/// A SQL client request.
#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
    /// Executes a SQL statement.
    Execute(String),
    /// Fetches the given table schema.
    GetTable(String),
    /// Lists all tables.
    ListTables,
    /// Returns server status.
    Status,
}

#[derive(Debug, Serialize, Deserialize)]
pub enum Response {
    Execute(StatementResult),
    Row(Option<Value>),
    GetTable(Table),
    ListTables(Vec<String>),
    //Status(Status),
    Err(u8, String),
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum StatementResult {
    //Begin(mvcc::TransactionState),
    //Commit { version: mvcc::Version },
    //Rollback { version: mvcc::Version },
    //Explain(Plan),
    CreateTable { name: String },
    DropTable { name: String, existed: bool },
    Delete { count: u64 },
    Insert { count: u64 },
    Update { count: u64 },
    // For simplicity, we buffer and send the entire set of rows as a vector
    // instead of streaming them to the client. Streaming reads haven't been
    // implemented from Raft either, so they're buffered all the way through.
    Select {rows: Vec<Entry> },
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Label {
    /// No label.
    None,
    /// An unqualified column name.
    Unqualified(String),
    /// A fully qualified table/column name.
    Qualified(String, String),
}